﻿using System.Linq;
using System.Windows;
using System.Windows.Media;

namespace DynamicGeometry
{
    public class PolygonCreator : FigureCreator
    {
        protected override void Click(Point coordinates)
        {
            var point = Drawing.Figures.HitTest<IPoint>(coordinates);
            if (point != null
                && !FoundDependencies.IsEmpty()
                && FoundDependencies.Count >= 4 // 4 including the TempPoint 
                                                // (and 3 after TempPoint is removed)
                && FoundDependencies[0] == point)
            {
                RemoveIntermediateFigureIfNecessary();
                if (TempPoint != null)
                {
                    FoundDependencies.Remove(TempPoint);
                    Drawing.Figures.Remove(TempPoint);
                    TempPoint = null;
                }
                Finish();
                return;
            }
            base.Click(coordinates);
        }

        protected override DependencyList InitExpectedDependencies()
        {
            return null;
        }

        protected override System.Type ExpectedDependency
        {
            get
            {
                return typeof(IPoint);
            }
        }

        protected override bool CanReuseDependency()
        {
            return true;
        }

        protected override IFigure CreateFigure()
        {
            return Factory.CreatePolygon(Drawing, FoundDependencies);
        }

        /// <summary>
        /// If there is no existing segment or line on a side of a polygon,
        /// create a new segment on each such side
        /// </summary>
        protected override void CreateAndAddFigure()
        {
            base.CreateAndAddFigure();
            for (int i = 0; i < FoundDependencies.Count; i++)
            {
                // get two consecutive vertices of the polygon
                int j = (i + 1) % FoundDependencies.Count;
                IPoint p1 = FoundDependencies[i] as IPoint;
                IPoint p2 = FoundDependencies[j] as IPoint;
                // try to find if there is already a line connecting them
                if (Drawing.Figures.FindLine(p1, p2) == null)
                {
                    // if not, create a new segment
                    var segment = Factory.CreateSegment(Drawing, new FigureList() { p1, p2 });
                    Drawing.Add(segment);
                }
            }
        }

        protected override IFigure CreateIntermediateFigure()
        {
            if (!FoundDependencies.All(f => f is IPoint))
            {
                return null;
            }
            if (FoundDependencies.Count == 2)
            {
                return Factory.CreateSegment(Drawing, FoundDependencies);
            }
            else if (FoundDependencies.Count >= 3)
            {
                var result = Factory.CreatePolygon(Drawing, FoundDependencies);
                result.Shape.Stroke = new SolidColorBrush(Colors.Black);
                return result;
            }
            return null;
        }

        public override string Name
        {
            get { return "Polygon"; }
        }

        public override string HintText
        {
            get
            {
                return "Click points to construct a polygon. Click the first point again to close the polygon.";
            }
        }

        public override System.Windows.Controls.Panel CreateIcon()
        {
            var builder = IconBuilder.BuildIcon();
            var polygon = builder.AddPolygon(
                new Point(0.2, 0.4),
                new Point(0.3, 0.8),
                new Point(0.7, 0.8),
                new Point(0.8, 0.4),
                new Point(0.6, 0.2)
            );
            polygon.Fill = Factory.CreateDefaultFillBrush();
            polygon.Stroke = new SolidColorBrush(Colors.Black);
            return builder.Canvas;
        }
    }
}